#include "yt_web.h"

#include <QtCore>
#include <QtGui>

////#include "nbr.h"
#include "t_core.h"
#include "xmlutil.h"

QByteArray YtWeb::doGet(QNetworkAccessManager *a_nam, QNetworkRequest a_request, QString *a_contentType)
{
    qDebug() << "doGet()" << a_request.url();
    QNetworkReply *v_reply = a_nam->get(a_request);
    //NetworkWaiter *v_nbr = new NetworkWaiter(v_reply);
    NetworkWaiter v_nbr(v_reply);
    v_nbr.wait();
    QByteArray v_response = v_nbr.just_readAll();
    if(a_contentType)
    {
        QByteArray v_contentType = v_reply->rawHeader("Content-Type");
        qDebug() << "[v_contentType]" << v_contentType;
        (*a_contentType) = v_contentType;
    }
    delete v_reply;
    ////delete v_nbr;
    return v_response;
}

QString YtWeb::getTokenForVideoStreamEmbed(QNetworkAccessManager *a_nam, QString a_id, QMap<int, QUrl> &a_fmt_map)
{
    //[Get Token]
    QString v_url_1 =
            QString("http://www.youtube.com/get_video_info?&video_id=%1&el=embedded&ps=default")
            //QString("http://www.youtube.com/get_video_info?&video_id=%1&el=detailpage&ps=&noflv=1")
            .arg(a_id);
    QByteArray v_params_1 = YtWeb::doGet(a_nam, v_url_1);
    v_params_1.prepend("?");
    QUrl v_params_2;
    v_params_2.setEncodedUrl(v_params_1);
    QString v_status = v_params_2.queryItemValue("status");
    QString v_reason = v_params_2.queryItemValue("reason");
    QString v_token = v_params_2.queryItemValue("token");
    QString v_allow_embed = v_params_2.queryItemValue("allow_embed");
    QString v_fmt_stream_map = v_params_2.queryItemValue("fmt_stream_map");
    //qDebug() << v_status << v_allow_embed << v_token << v_fmt_stream_map;
    if(v_status == "fail")
    {
        //g_Env->showMessage(v_reason);
    }
    else
    {
        //g_Env->showMessage("");
    }
    if(v_token == "")
    {
        qDebug() << v_params_2;
    }
    a_fmt_map.clear();
    if(v_fmt_stream_map != "")
    {
        QStringList v_slist_1 = v_fmt_stream_map.split(',');
        for(int i=0; i<v_slist_1.size(); i++)
        {
            QStringList v_slist_2 = v_slist_1.at(i).split('|');
            int v_fmt = v_slist_2.at(0).toInt();
            QString v_stream_url_1 = v_slist_2.at(1);
            QUrl v_stream_url_2;
            v_stream_url_2.setEncodedUrl(v_stream_url_1.toLatin1());
            a_fmt_map.insert(v_fmt, v_stream_url_2);
        }
    }
    qDebug() << "[v_token(embed)]" << v_token;
    qDebug() << "[a_fmt_map.keys()]" << a_fmt_map.keys();
    return v_token;
}

QString YtWeb::getTokenForVideoStreamDetail(QNetworkAccessManager *a_nam, QString a_id, QMap<int, QUrl> &a_fmt_map)
{
    QString v_watch_url =
            QString("http://www.youtube.com/watch?v=%1")
            .arg(a_id);
    qDebug() << "[v_watch_url]" << v_watch_url;
    QByteArray v_html_raw = YtWeb::doGet(a_nam, v_watch_url);
    //qDebug() << "[v_html_raw]" << v_html_raw;
    qDebug() << "[v_html_raw.size()]" << v_html_raw.size();
    QString v_html_str = QString::fromUtf8(v_html_raw);
    //qDebug() << "[v_html_str]" << v_html_str;

    int v_pos = 0;

    QRegExp v_rxStream("[?&](fmt_stream_map=[^&'\"\\\\]+)");
    v_pos = v_rxStream.indexIn(v_html_str, 0);
    a_fmt_map.clear();
    if(v_pos != -1)
    {
        QByteArray v_params_raw = v_rxStream.cap(1).toLatin1();
        v_params_raw.prepend("?");
        QUrl v_params_url;
        v_params_url.setEncodedUrl(v_params_raw);
        QString v_fmt_stream_map = v_params_url.queryItemValue("fmt_stream_map");
        if(v_fmt_stream_map != "")
        {
            QStringList v_slist_1 = v_fmt_stream_map.split(',');
            for(int i=0; i<v_slist_1.size(); i++)
            {
                QStringList v_slist_2 = v_slist_1.at(i).split('|');
                int v_fmt = v_slist_2.at(0).toInt();
                QString v_stream_url_1 = v_slist_2.at(1);
                QUrl v_stream_url_2;
                v_stream_url_2.setEncodedUrl(v_stream_url_1.toLatin1());
                a_fmt_map.insert(v_fmt, v_stream_url_2);
            }
        }
    }


    QRegExp v_rxToken("[?&](t=[^&'\"\\\\]+)");

    v_pos = v_rxToken.indexIn(v_html_str, 0);
    qDebug() << "[pos]" << v_pos;
    if(v_pos == -1)
    {
        return "";
    }
    else
    {
        QByteArray v_params_raw = v_rxToken.cap(1).toLatin1();
        v_params_raw.prepend("?");
        QUrl v_params_url;
        v_params_url.setEncodedUrl(v_params_raw);
        QString v_token = v_params_url.queryItemValue("t");
        qDebug() << "[v_token(detail)]" << v_token;
        qDebug() << "[a_fmt_map.keys()]" << a_fmt_map.keys();
        return v_token;
    }
}

/*
http://code.google.com/p/get-flash-videos/source/browse/trunk/FlashVideo/Site/Youtube.pm?r=311
my @formats = (
  { id => 37, resolution => [1920, 1080] },
  { id => 22, resolution => [1280, 720] },
  { id => 35, resolution => [854, 480] },
  { id => 34, resolution => [640, 360] },
  { id => 18, resolution => [480, 270] },
  { id => 5,  resolution => [400, 224] },
  { id => 17, resolution => [176, 144] },
  { id => 13, resolution => [176, 144] },
);
*/
/*****
QUrl YtWeb::getUrlForVideoStream(QString a_id, int a_fmt)
{
    if(a_fmt < 0)
    {
        a_fmt = 34;
    }
    //[Get Token]
    QMap<int, QUrl> v_fmt_map;
    QString v_token = getTokenForVideoStreamEmbed(a_id, v_fmt_map);

    if(v_token == "")
    {
        v_token = getTokenForVideoStreamDetail(a_id, v_fmt_map);
    }

    if(v_fmt_map.contains(a_fmt))
    {
        return v_fmt_map.value(a_fmt);
    }

    if(!v_fmt_map.contains(34) && v_fmt_map.contains(5))
    {
        a_fmt = 5;
    }

    qDebug() << "[v_token]" << v_token;

    //[Get Video Location]
    QUrl v_video_url("http://www.youtube.com/get_video");
    v_video_url.addQueryItem("video_id", a_id);
    v_video_url.addQueryItem("t", v_token);
    if(a_fmt >= 0)
    {
        QString v_fmt = QString("%1").arg(a_fmt);
        v_video_url.addQueryItem("fmt", v_fmt);
    }
    QByteArray v_location = NetworkThreadRequest::doGet2(v_video_url);
    qDebug() << "[v_location]" << v_location;

    //[Return Video Stream Url]
    QUrl v_result;
    v_result.setEncodedUrl(v_location);

    return v_result;
}
*****/

QString YtWeb::getVideoStreamMap(QNetworkAccessManager *a_nam, QString a_id, QMap<int, QUrl> &a_fmt_map)
{
    //[Get Token & Stream Map]
    QString v_token = getTokenForVideoStreamEmbed(a_nam, a_id, a_fmt_map);
    if(v_token == "")
    {
        v_token = getTokenForVideoStreamDetail(a_nam, a_id, a_fmt_map);
    }
    qDebug() << "[v_token(getVideoStreamMap)]" << v_token;
    qDebug() << "[a_fmt_map.keys()]" << a_fmt_map.keys();
    return v_token;
}

void YtWeb::getVideoAttributes(QNetworkAccessManager *a_nam, QString a_id)
{
    QString v_url_str = QString("http://gdata.youtube.com/feeds/api/videos/%1").arg(a_id);
    QUrl v_url(v_url_str);
    //g_Env->showMessage(v_url.toString());
    QByteArray v_xml = YtWeb::doGet(a_nam, v_url);
    XmlUtil::backupXmlBody(v_xml, "getVideoAttributes");
    if(v_xml == "Video not found")
    {
        //v_rec->view_count = -1;
    }
    else
    {
        QDomDocument domDocument;
        if(XmlUtil::setXmlContent(domDocument, v_xml))
        {
            QDomElement v_entry = domDocument.documentElement();
            // [/entry/yt:statistics(viewCount)]
            QDomNodeList v_stat_list = v_entry.elementsByTagNameNS("http://gdata.youtube.com/schemas/2007", "statistics");
            QDomElement v_stat_elem = v_stat_list.at(0).toElement();
            qint64 v_view_count = v_stat_elem.attribute("viewCount").toLongLong();
            qDebug() << "[YtWeb::getVideoAttributes] v_view_count" << v_view_count;
            // [/entry/title]
            QDomNodeList v_title_list = v_entry.elementsByTagNameNS("http://www.w3.org/2005/Atom", "title");
            QDomElement v_title_elem = v_title_list.at(0).toElement();
            QString v_title = v_title_elem.text();
            qDebug() << "[YtWeb::getVideoAttributes] v_title" << v_title;
        }
    }
}
